В этом шаге нарисуем кубик и посмотрим как влияют установки вида на вид кубика.
Как обычно делаем проект. Добавим в проект 2 переменных: m_iMode - определяет режим вывода граней куба, m_fFar - определяет дальнее расстояние границ пространства.
Для упрощения функции OnDraw(...) добавим функцию DrawCube(void), которая будет просто рисовать куб, отрисовывая последовательно все его 6 граней. Чтобы посмотреть разные режимы отображения полигонов сделаем пункт меню (View->Mode) и сделаем его (меню) обработчик, который будет изменять режим. Вот его код:
void CExampleView::OnViewMode()
{
// TODO: Add your command handler code here
if(m_iMode>=2)
m_iMode = 0;
else
m_iMode++;
InvalidateRect(NULL, FALSE);
}
Комментарии излишни. Теперь сделаем обработчик от клавиатуры. Напишем его так, чтобы при нажатии на стрелку вверх дальняя граница пространства отодвигалась, а при нажатии на стрелку вниз - приближалась. Допустим такой код:
void CExampleView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
if(nChar==VK_UP)
m_fFar+=0.5f;
if(nChar==VK_DOWN)
m_fFar-=0.5f;
InvalidateRect(NULL, FALSE);
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
Разумеется, незабудьте создать переменные m_iMode и m_fFar и проинициализировать их в конструкторе.
Теперь наша многострадальная функция OnDraw(...) примет следующий вид:
void CExampleView::OnDraw(CDC* pDC)
{
CRect clientRect;
CExampleDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
GetClientRect(&clientRect);
glViewport(0, 0, clientRect.right, clientRect.bottom);
glClearColor (0.5, 0.5, 0.75, 1.0);
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 0.0, 0.5);
glLoadIdentity();
glFrustum (-1, 1, -1, 1, 3, m_fFar);
glTranslatef(0.0, 0.0, -8.0);
glRotatef(30.0, 1.0, 0.0, 0.0);
glRotatef(70.0, 0.0, 1.0, 0.0);
switch(m_iMode)
{
case 0:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
break;
case 1:
glEnable(GL_POINT_SMOOTH);
glPointSize(10);
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
break;
case 2:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
break;
}
DrawCube();
SwapBuffers(pDC->m_hDC);
}
Где функция DrawCube(void) выглядит так:
GLvoid CExampleView::DrawCube()
{
glBegin (GL_QUADS);
glVertex3f (1.0, 1.0, 1.0);
glVertex3f (-1.0, 1.0, 1.0);
glVertex3f (-1.0, -1.0, 1.0);
glVertex3f (1.0, -1.0, 1.0);
glEnd();
glBegin (GL_QUADS);
glVertex3f (1.0, 1.0, -1.0);
glVertex3f (1.0, -1.0, -1.0);
glVertex3f (-1.0, -1.0, -1.0);
glVertex3f (-1.0, 1.0, -1.0);
glEnd();
glBegin (GL_QUADS);
glVertex3f (-1.0, 1.0, 1.0);
glVertex3f (-1.0, 1.0, -1.0);
glVertex3f (-1.0, -1.0, -1.0);
glVertex3f (-1.0, -1.0, 1.0);
glEnd();
glBegin (GL_QUADS);
glVertex3f (1.0, 1.0, 1.0);
glVertex3f (1.0, -1.0, 1.0);
glVertex3f (1.0, -1.0, -1.0);
glVertex3f (1.0, 1.0, -1.0);
glEnd();
glBegin (GL_QUADS);
glVertex3f (-1.0, 1.0, -1.0);
glVertex3f (-1.0, 1.0, 1.0);
glVertex3f (1.0, 1.0, 1.0);
glVertex3f (1.0, 1.0, -1.0);
glEnd();
glBegin(GL_QUADS);
glVertex3f (-1.0, -1.0, -1.0);
glVertex3f (1.0, -1.0, -1.0);
glVertex3f (1.0, -1.0, 1.0);
glVertex3f (-1.0, -1.0, 1.0);
glEnd();
}
Единственная особенность новой OnDraw(...) - это 2 команды glRotatef(...), которые просто поворачивают систему координат для удобного простора объекта. Если вы закомментируете эти функции, станет понятно их предназначение.
Вот собственно и все. Соберите проект и понажимайте стрелки...